package com.gitee.yusugar.core.util;

import cn.hutool.core.lang.caller.CallerUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.LogFactory;
import com.gitee.yusugar.common.YuToolServiceException;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
public class LogUtil {

    public static String basePackage;

    /**
     * 生成系统错误日志
     *
     * @param throwable 异常信息
     * @return 生成的错误信息
     */
    public static String buildErrInfo( Throwable throwable ) {
        if ( StrUtil.isBlank( basePackage ) )
            throw new YuToolServiceException( "未设置 basePackage." );

        // 获取该项目类的异常
        StackTraceElement[] stackTrace = throwable.getStackTrace();
        List<StackTraceElement> exceptionClass = Arrays.stream( stackTrace )
                .filter( o -> {
                    String fileName = o.getFileName();
                    return o.getClassName().startsWith( basePackage ) && !( StrUtil.isBlank( fileName ) || "<generated>".equals( fileName ) );
                } ).collect( Collectors.toList() );

        if ( exceptionClass.isEmpty() )
            return String.format( "record log info：【%s】", throwable.getMessage() );
        else {
            StringBuilder errorLineNumber = new StringBuilder();
            exceptionClass.forEach( e -> {
                String fileName = e.getFileName();
                errorLineNumber.append( "->【" )
                        .append( fileName, 0, Objects.requireNonNull( fileName ).lastIndexOf( "java" ) )
                        .append( e.getMethodName() )
                        .append( ": " ).append( e.getLineNumber() )
                        .append( " 行】" );
            } );
            return String.format( "record log info:【%s】. Caused by:【%s】", throwable.getMessage(), errorLineNumber.substring( 2 ) );
        }
    }

    /**
     * 记录系统错误日志
     *
     * @param throwable 异常信息
     */
    public static void recordErr( Throwable throwable ) {
        LogFactory.get(CallerUtil.getCallerCaller()).error( buildErrInfo( throwable ) );
    }
}
